﻿using System;
using System.Collections.Generic;

namespace net.zxteam.ZXLexer
{
	using System.IO;
	using System.Xml;
	using net.zxteam.ZXLexer.AST;
	
    using net.zxteam.ZXLexer.Dynamic;
    using net.zxteam.ZXLexer.Tokens;


	class EntryPoint
	{
		static void Main(string[] args)
		{
			EmbeddedAssemblyResolver.Instance.Ping();
			ParserFactory.Instance.Ping();

			ProgramArgs pArgs = ProgramArgsParser.Parse(args);
			if (pArgs.Help)
			{
				if (pArgs.ParseException != null)
				{
					Console.WriteLine(pArgs.ParseException.Message);
					System.Environment.Exit(1);
				}
				pArgs.ShowHelp(Console.Out);
				System.Environment.Exit(0);
			}

			new EntryPoint(pArgs).Run();
		}


		private EntryPoint(ProgramArgs pArgs)
		{
			if (pArgs == null) throw new ArgumentNullException();

			_pArgs = pArgs;
		}

		private void Run()
		{
            ILexer lexer;
            using (FileStream fs = new FileStream(@"..\..\..\..\..\\Annotation\ZX.Code.Primitives.peg", FileMode.Open))
            //using (FileStream fs = new FileStream(@"..\..\..\..\..\\Annotation\net.zxteam.zxlang1.peg", FileMode.Open))
            {
                var astRule = ZXLexer.Rules.Rule.LoadGrammar(fs);
                lexer = new DynamicLexer(astRule);
            }


            //ZXLexer.Runtime.RuntimeLexer lexer;
            //using (FileStream fs = new FileStream(@"..\..\..\..\..\\Annotation\ZX.Code.Primitives.peg", FileMode.Open))
            ////using (FileStream fs = new FileStream(@"..\..\..\..\..\\Annotation\net.zxteam.zxlang1.peg", FileMode.Open))
            //{
            //    lexer = new ZXLexer.Runtime.RuntimeLexer(fs);
            //}

			string code;
			using (StreamReader sr = new StreamReader(@"..\..\..\..\..\Examples\0000.Primitive.zx1"))
			{
				string line;
				while (true)
				{
					line = sr.ReadLine();
					if (line.StartsWith("!"))
					{
						// file digital sign
					}
					else if (line.StartsWith("#"))
					{
						// file annotation (information, author, etc)
					}
					else
					{
						string tail = sr.ReadToEnd();
						if (!string.IsNullOrEmpty(tail))
						{
							code = line + Environment.NewLine + tail;
						}
						else
						{
							code = line;
						}

						break;
					}
				}
			}

			IAstToken dynamicAst = lexer.Tokenize(new StringLexerSource(code));

			//var parserGenerator = ParserAssemblyGenerator.ParserAssemblyGeneratorFactory.Instance.CreateParserGenerator();
			//var parserAssembly = parserGenerator.Generate(@"C:\Users\maxim.anurin\Work\zxlang\Annotation\net.zxteam.zxlang.peg");
			//var parserAssembly = parserGenerator.Generate(@"C:\Users\anurinm\Work\zxlang\Annotation\net.zxteam.zxlang1.peg");


			//Type parserType = EmbeddedAssemblyResolver.Instance.GetEmbeddedParserType("net.zxteam.zxlang");
			//IParser parser = ParserFactory.Instance.CreateParser("net.zxteam.zxlang1");

			//IParser parser = (IParser)Activator.CreateInstance(parserType);

			// http://habrahabr.ru/post/104968/
			//var p = parser.Parse(@"\int_{-\frac{\pi}{2}}^{\frac{\pi}{2}} \cos x \; dx = 2");

			//ASTNode ast = parser.Parse(code);
            //using (MemoryStream ms = new MemoryStream())
            //using (XmlWriter writer = XmlWriter.Create(ms, new XmlWriterSettings() { 
            //    Indent = true,
            //    }))
            //{
            //    dynamicAst.Render(writer);
            //    ms.Seek(0, SeekOrigin.Begin);
            //    using (FileStream resultFile = new FileStream("result.xml", FileMode.Create, FileAccess.Write, FileShare.Read))
            //    {
            //        ms.CopyTo(resultFile);
            //        resultFile.Close();
            //    }
            //}
		}

		private readonly ProgramArgs _pArgs;
	}


}
